{\rtf0\ansi{\fonttbl\f0\fmodern Courier;\f1\ftech Symbol;\f2\fmodern Ohlfs;}
\margl40
\margr40
{\colortbl;\red0\green0\blue0;}
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i0\ulnone\fs24\fc0\cf0 //ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//
\i 	
\b FILENAME
\b0 :	
\b\i0 Inspector.m \

\b0 //
\i 	
\b SUMMARY
\b0 :	
\b\i0 Implementation of a NeXTSTEP-style inspector using <Inspectable>\

\b0 //	
\b\i SUPERCLASS
\b0 :
\i0 	
\b Object:Inspector
\b0 \
//	
\b\i PROTOCOLS
\b0 :
\i0 	
\b <Inspectable>
\b0 \
//	
\b\i INTERFACE
\b0 :
\i0 	
\b Inspector.nib
\b0 \
//	
\b\i AUTHOR
\b0 :		
\b\i0 Rohit Khare
\b0 \
//	
\b\i COPYRIGHT
\b0 :	
\f1\i0 с
\f0\b 1993,94 California Institure of Technology, eText Project\

\b0 //ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//	
\b\i Implementation Comments
\b0\i0 \
//		Still uses the neato self-inspection trick for "No Selection"\
//		This panel uses Andrew Stone's WidePopUpManager to mediate.\
//ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//	
\b\i History
\b0\i0 \
//	10/30/93:	
\b Added refresh: (see setDocPath in eTDocInfo)
\b0 \
//	10/30/93:	
\b Removed invalidate: (Obsolete, not called)
\b0 \
//	10/30/94:	
\b Modified to implement <InspectorTarget> protocol.
\b0 \
//	09/27/94:	
\b Revamped for eText5; added WidePopupManager.
\b0 \
//	02/04/94:	
\b Modified invalidate to "tunnel" through to display etDocInfoUI
\b0 \
//	01/12/94:	
\b Reworked header file dependency
\b0 \
//	08/22/93:	
\b Added invalidate:
\b0 \
//	08/18/93:	
\b Created. Derived almost wholly from Version 1.0
\b0 \
//	
\i Version 1.0 tracking notes:
\i0 \
//	06/29/93: 	
\b Added conformance for touch (currentDoc)
\b0 \
// 	06/27/93: 	
\b Created (Rohit Khare)
\b0 \
//ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//	
\b Imported Interfaces
\b0 \
//\
	#import "
\b Inspector.h
\b0 "\
	#import "
\b Kludges
\b0 .subproj/
\b WidePopupManager.h
\b0 "\
\

\i @implementation Inspector\

\i0 //ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//	
\b Class Management
\b0 \
//\
- 
\b init
\b0  \{\
    [
\b super
\b0  
\b init
\b0 ];\
 	
\b current
\b0  = 
\b nil
\b0 ;\
 	
\b currentTarget
\b0  = 
\b nil
\b0 ;\
	
\b currentView
\b0  = 
\b nil
\b0 ;\
	
\b currentType
\b0  = 
\b NULL
\b0 ;\
	
\b typesForInspector
\b0  = 
\b NULL
\b0 ;\
	[NXApp 
\b loadNibSection
\b0 :"
\b Inspector
\b0 .
\b nib
\b0 " 
\b owner
\b0 :
\b self
\b0  withNames:NO];\

\i 	//if ([[NXApp userModel] boolQuery:"InspectorFloat"])\

\i0 	[panel 
\b setFloatingPanel
\b0 :
\b YES
\b0 ];\
	[panel 
\b setExcludedFromWindowsMenu
\b0 :
\b YES
\b0 ];\
	[panel 
\b setFrameAutosaveName
\b0 :"
\b etInspectorPanel
\b0 "];\
	[panel setFrameUsingName:"etInspectorPanel"];\
	[self 
\b inspect
\b0 :
\b self
\b0 ];\
	
\b return self
\b0 ;\
\}\
\
- 
\b free
\b0  \{\
	panel = [
\b panel
\b0  free];\
	invalidPanel = [
\b invalidPanel
\b0  free];\
	infoPanel = [
\b infoPanel
\b0  free];\
	return self = [
\b super
\b0  free];\
\}\
\
- 
\b awakeFromNib
\b0  \{\
	
\b cover
\b0  = 
\b popup
\b0 ;\
    
\b if
\b0  (
\b !
\b0 [
\b popup
\b0  
\b isKindOf
\b0 :[
\b PopUpList
\b0  class]]) 
\b popup
\b0  = [
\b popup
\b0  
\b target
\b0 ];\
	[[
\b popup
\b0  setTarget:self] 
\b setAction
\b0 :@selector(
\b swap
\b0 :)];\

\fc1\cf1 	[[
\b WidePopupManager
\b0  alloc] 
\b initForButton
\b0 :cover 
\b andList
\b0 :popup];\

\fc0\cf0 	
\b invalidView
\b0  = [invalidPanel 
\b contentView
\b0 ];\
	
\b infoView
\b0  = [infoPanel 
\b contentView
\b0 ];\
	return self;\
\}\
\
//ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//	
\b User Interface
\b0 \
//\
- 
\b showInspector
\b0  \{\
	[
\b panel
\b0  
\b makeKeyAndOrderFront
\b0 :self];\
	return self;\
\}\
\
- 
\b swap
\b0 :sender \{\
	
\b if
\b0 (
\b strcmp
\b0 ([popup 
\b selectedItem
\b0 ], 
\b currentType
\b0 )) \{\
		[panel 
\b disableDisplay
\b0 ];		// 
\i Disable display
\i0 \
		[
\b current
\b0  
\b resignInspector
\b0 :
\b currentView
\b0  
\b ofType
\b0 :
\b currentType
\b0 ];\
		[
\b currentView
\b0  
\b removeFromSuperview
\b0 ];\
		// 
\i Swap in the view for the selected cell of the popup
\i0 \
		
\b currentType
\b0  = (char *) [popup 
\b selectedItem
\b0 ];\
		
\b currentView
\b0  = [
\b current
\b0  
\b inspectorForType
\b0 : 
\b currentType
\b0 ];\
		[
\b currentView
\b0  
\b sizeTo
\b0 :INSPECTOR_W :INSPECTOR_H];\
		[[panel contentView] 
\b addSubview
\b0 :
\b currentView
\b0 ];\
		[
\b current
\b0  
\b activateInspector
\b0 :
\b currentView
\b0  
\b ofType
\b0 : 
\b currentType
\b0 ];\
		[panel 
\b reenableDisplay
\b0 ];		// 
\i Reenable display
\i0 \
		[panel 
\b display
\b0 ];\
	\}\
	
\b if
\b0 (
\b strcmp
\b0 ([popup 
\b selectedItem
\b0 ], [cover 
\b title
\b0 ])) \{\
		[cover 
\b setTitle
\b0 :[popup 
\b selectedItem
\b0 ]];\
	\}\
	return self;\
\}\
\
//ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//	
\b Public Inspector API
\b0 \
//\
\
- 
\b inspect
\b0 : 
\b newObj
\b0  \{			// 
\i Can be 
\i0 <
\b Inspectable
\b0 >
\i  or 
\i0 <
\b InspectableTarget
\b0 >
\i ;\

\i0 	int i,j;\
	char **
\b types
\b0 ;\
	char str[256];\
	\
	if (
\b newObj
\b0  == 
\b nil
\b0 ) 
\b newObj
\b0 =
\b self
\b0 ;	// 
\i Sanity Check: is this a nil object?\
	
\i0 // 
\i Sanity Check: is this a new target or 
\i0 <InspectableTarget>
\i  object?
\i0 \
	if (([
\b newObj
\b0  
\b respondsTo
\b0 :@selector(
\b inspectableDelegate
\b0 )] \
		&& (
\b newObj == currentTarget
\b0 ))\
		|| (
\b newObj
\b0  == 
\b current
\b0 ))\
			
\b return
\b0  self;\
		\
	[panel 
\b disableDisplay
\b0 ];			// 
\i Disable display
\i0 \
	[
\b current
\b0  
\b resignInspector
\b0 :
\b currentView
\b0  
\b ofType
\b0 :
\b currentType
\b0 ];\
	if ([
\b currentView
\b0  
\b window
\b0 ] == 
\b panel
\b0 )\
		[currentView 
\b removeFromSuperview
\b0 ];	\
	i = [popup 
\b count
\b0 ];					// 
\i Empty out the current popup
\i0 \
	for (j = 0; j < i; j++) [popup 
\b removeItemAt
\b0 :
\b j
\b0 ];\
	\
	// 
\i Now reset current, currentTarget, potentially using <InspectableTarget>\
	
\i0 if ([
\b newObj
\b0  
\b respondsTo
\b0 :@selector(
\b inspectableDelegate
\b0 )]) \{\
		
\b current
\b0  = [
\b newObj
\b0  
\b inspectableDelegate
\b0 ];\
		
\b currentTarget
\b0  = 
\b newObj
\b0 ;\
	\} else \{\
		
\b current
\b0  = 
\b newObj
\b0 ;\
		
\b currentTarget
\b0  = 
\b nil
\b0 ;\
	\}\
	\
	
\b types
\b0  = (char **)[
\b current
\b0  
\b types
\b0 ];\
	i = 0;\
	while (types[i]) \{			// 
\i Load in the new popup with names and actions\

\i0 		[[
\b popup
\b0  
\b addItem
\b0 :NXUniqueString(
\b types[i]
\b0 )] \
			
\b setKeyEquivalent
\b0 :(i < 5) ? ('
\b 5
\b0 '+ 
\b i
\b0 ) : '
\b \\0
\b0 '];\
		i++;\
	\}\
	[
\b cover
\b0  
\b setTitle
\b0 :
\b types
\b0 [
\b 0
\b0 ]];		// 
\i Load in the default inspector
\i0 \
	[[
\b popup
\b0  itemList] 
\b selectCellAt
\b0 :
\b 0
\b0 :0];\
	
\b currentType
\b0  = (char *) 
\b types
\b0 [
\b 0
\b0 ];\
	
\b currentView
\b0  = [current 
\b inspectorForType
\b0 :
\b currentType
\b0 ];\
	[currentView 
\b sizeTo
\b0 :INSPECTOR_W :INSPECTOR_H];\
	[[panel contentView] 
\b addSubview
\b0 :currentView];\
	[current 
\b activateInspector
\b0 :
\b currentView
\b0  ofType:currentType];\
	sprintf(str, "
\b %s Inspector
\b0 ", [current 
\b inspectorTitle
\b0 ]);\
	[
\b panel
\b0  
\b setTitle
\b0 :NXUniqueString(
\b str
\b0 )];\
	//[self 
\b showInspector
\b0 ];			// 
\i Redisplay
\i0 \
	[[panel 
\b reenableDisplay
\b0 ] 
\b display
\b0 ];\
	return self;\
\}\
\
- 
\b invalidate
\b0  \{					// 
\i Obsolete! Not called in kernel, comp. warnings\

\i0 	id it;\
	\
	if (
\b current
\b0  == 
\b self
\b0 ) 
\b return
\b0  self;\
	if (
\b it
\b0 =[[[NXApp mainWindow] delegate] 
\b etDoc
\b0 ])\{\
		[
\b it
\b0  
\b setSelectedObj
\b0 :
\b nil
\b0 ];\
		[self 
\b inspect
\b0 :[
\b it
\b0  
\b selectedObj
\b0 ]];\
	\} 
\b else
\b0  \{\
		[self 
\b inspect
\b0 :
\b nil
\b0 ];\
	\}\
	return self;\
\}\
\
- 
\b currentObj
\b0  \{
\b return
\b0  (
\b currentTarget 
\b0 ? 
\b currentTarget
\b0  : 
\b current
\b0 );\}\
\
- 
\b makeFirstResponder
\b0 :aView \{\
	
\b return
\b0  (([[panel 
\b contentView
\b0 ] 
\b findAncestorSharedWith
\b0 :
\b aView
\b0 ] == panel) ? [
\b panel
\b0  
\b makeFirstResponder
\b0 :aView] : 
\b nil
\b0 );\
\}\
\
- 
\b refresh
\b0  \{\
	[
\b current
\b0  
\b activateInspector
\b0 :
\b currentView
\b0  
\b ofType
\b0 :
\b currentType
\b0 ]; return self;\}\
\
//ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//	
\b Private Inspector API
\b0 \
//\
- 
\b freeze
\b0  \{\
	[panel 
\b disableDisplay
\b0 ];\
	[
\b current
\b0  
\b resignInspector
\b0 :
\b currentView
\b0  
\b ofType
\b0 :
\b currentType
\b0 ];\
	return self;\
\}\
- 
\b thaw
\b0  \{\
	[
\b current
\b0  
\b activateInspector
\b0 :
\b currentView
\b0  
\b ofType
\b0 :
\b currentType
\b0 ];\
	[[panel 
\b reenableDisplay
\b0 ] 
\b display
\b0 ];\
	return self;\
\}\
\
//ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//	
\b Introspection: <Inspectable> Obligations
\b0 \
//\
#define 
\b NOSEL
\b0 	"
\b No Selection
\b0 "\
#define 
\b INFO
\b0 	"
\b Info
\b0 "\
\
- (const NXAtom *) 
\b types 
\b0 \{\
	if (
\b !typesForInspector
\b0 ) \{\
		
\b typesForInspector
\b0  = 
\b malloc
\b0 (
\b 3
\b0 *sizeof(char *));\
		typesForInspector[0] = (char *) NXUniqueString(
\b NOSEL
\b0 );\
		typesForInspector[1] = (char *) NXUniqueString(
\b INFO
\b0 );\
		typesForInspector[2] = 
\b NULL
\b0 ;\
	\}\
	return 
\b typesForInspector
\b0 ;\
\}\
\
- 
\b inspectorForType
\b0 :(const char *) 
\b type
\b0  \{\
	if(
\b !strcmp
\b0 (type,NXUniqueString(
\b NOSEL
\b0 )))\
		return 
\b invalidView
\b0 ;\
	else if (
\b !strcmp
\b0 (type,NXUniqueString(
\b INFO
\b0 )))\
		return 
\b infoView
\b0 ;\
	NXLogError("
\b Massive Inspector Failure: Asked Inspector for: %s
\b0 ", 
\b type
\b0 );\
	return 
\b invalidView
\b0 ;\
\}\
\
- 
\b resignInspector
\b0 : (View *) oldInspector 
\b ofType
\b0 : (const char *) type \{\
	
\b return
\b0  self;\}\
\
- 
\b activateInspector
\b0 : (View *) newInspector 
\b ofType
\b0 : (const char *) type \{\
	
\b return
\b0  self;\}\
\
- (const char *) 
\b inspectorTitle
\b0  \{return NXUniqueString("
\b eText
\b0 ");\}\
\
@end
}
